package com.jingdianjichi.subject.domain.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 线程池config管理
 */
@Configuration
public class ThreadPoolConfig {
    @Bean(name = "labelThreadPool")
    public ThreadPoolExecutor getLabelThreadPool(){
//      核心线程执行任务->全部核心线程都在执行任务时来了新任务,往队列里加->队列任务满时，创建新线程直到最大线程数->最大线程数拉满了，执行最后的策略
        return new ThreadPoolExecutor(20,
//              线程池中允许的最大线程数。当任务队列满了，且已运行的线程数小于最大线程数时，线程池会尝试创建新的线程来执行任务。
                100,5, TimeUnit.MINUTES,
/**
 * 队列，当线程数目超过核心线程数时用于保存任务的队列。（BlockingQueue workQueue）此队列仅保存实现Runnable接口的任务。
 * 因为线程池的底层BlockingQueue的泛型为Runnable）
 * LinkedBlockingDeque实现了BlockingDeque接口是个双端队列并且是线程安全的，是线程安全的，支持多个线程同时访问队列。
 * 它通过内部锁（如ReentrantLock）和条件变量（如Condition）来实现并发控制
 */
                new LinkedBlockingDeque<>(40),
//             为了统一在创建线程时设置一些参数，如是否守护线程，线程一些特性等，如优先级
                new CustomNameThreadFactory("label"),
/**
 *  AbortPolicy 丢弃任务，抛运行时异常。
 *  CallerRunsPolicy 由当前调用的任务线程执行任务。(而不是这个线程池了)
 *  DiscardPolicy 忽视，什么都不会发生。
 *  DiscardOldestPolicy 从队列中踢出最先进入队列（最后一个执行）的任务。
 */
                new ThreadPoolExecutor.CallerRunsPolicy());
    }
}
